<template>
  <div class="progress-container" ref="containerRef">
    <canvas ref="canvasRef" class="progress-canvas"></canvas>
    <div
      class="progress-text"
      v-if="showText"
      :style="{ color: textColor, fontSize: `${textSize}px` }"
    >
      <p>{{ topNumber }}</p>
      <p class="bottom-number" style="margin-top: 10px; font-size: 16px;">{{  bottomNumber }}</p>
    </div>
  </div>
</template>

<script lang="ts" setup>
import { ref, onMounted, onUpdated, onUnmounted, watch, PropType, computed } from 'vue'

// 定义组件属性
const props = defineProps({
  percentage: {
    type: Number,
    required: true,
    validator: (val: number) => val >= 0 && val <= 100
  },
  topNumber: {
    type: String,
    required: true
  },
  bottomNumber: {
    type: String,
    required: true
  },
  size: {
    type: Number,
    default: 100
  },
  // 外层圆环样式
  outerStrokeWidth: {
    type: Number,
    default: 15
  },
  innerStrokeWidth: {
    type: Number,
    default: 7
  },
  startColor: {
    type: String,
    default: '#4cd964'
  },
  endColor: {
    type: String,
    default: '#5ac8fa'
  },
  bgColor: {
    type: String,
    default: 'rgba(0,0,0,0)'
  },
  //默认顺时针方向画圆
  clockwise: {
    type: Boolean,
    default: true
  },
  showText: {
    type: Boolean,
    default: true
  },
  textColor: {
    type: String,
    default: '#fff'
  },
  textSize: {
    type: Number,
    default: 28
  },
  startAngle: {
    type: Number,
    default: Math.PI * 1.5 // 从12点钟方向开始
  },
  // 动画效果
  animate: {
    type: Boolean,
    default: true
  },
  animationDuration: {
    type: Number,
    default: 1500
  },
  // 自定义文本显示
  textFormat: {
    type: Function as PropType<(percentage: number) => string>,
    default: (percentage: number) => `${percentage}%`
  }
})

// 获取DOM引用
const canvasRef = ref<HTMLCanvasElement | null>(null)
const containerRef = ref<HTMLDivElement | null>(null)
const animationFrameId = ref<number | null>(null)

// 计算显示值
const displayValue = computed(() => props.textFormat(props.percentage))

// 绘制进度条
const drawProgressRing = (currentPercentage: number = props.percentage) => {
  if (!canvasRef.value) return

  const canvas = canvasRef.value
  const ctx = canvas.getContext('2d')
  if (!ctx) return

  // 设置Canvas尺寸（考虑设备像素比以确保清晰度）
  const dpr = window.devicePixelRatio || 1
  const size = props.size
  canvas.width = size * dpr
  canvas.height = size * dpr
  canvas.style.width = `${size}px`
  canvas.style.height = `${size}px`

  // 缩放上下文以匹配设备像素比
  ctx.scale(dpr, dpr)

  // 清除画布
  ctx.clearRect(0, 0, size, size)

  // 计算圆环参数
  const center = size / 2
  const outerRadius = (size - props.outerStrokeWidth) / 2 - 1
  const innerRadius = outerRadius - props.outerStrokeWidth / 2 + props.innerStrokeWidth / 2

  // 计算当前角度
  const endAngle =
    props.startAngle + (props.clockwise ? 1 : -1) * (currentPercentage / 100) * Math.PI * 2

//   // 定义颜色断点
//   const colorStops = [
//     { percentage: 0, color: '#F44336' }, // 红色 (0%)
//     { percentage: 50, color: '#FFC107' }, // 黄色 (50%)
//     { percentage: 100, color: '#4CAF50' } // 绿色 (100%)
//   ]
//   // 添加颜色插值函数
//   const interpolateColor = (color1: string, color2: string, factor: number): string => {
//     // 辅助函数：将十六进制颜色转换为RGB数组
//     const hexToRgb = (hex: string) => {
//       const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex)
//       return result
//         ? [parseInt(result[1], 16), parseInt(result[2], 16), parseInt(result[3], 16)]
//         : [0, 0, 0]
//     }

//     const rgb1 = hexToRgb(color1)
//     const rgb2 = hexToRgb(color2)

//     // 计算插值后的RGB值
//     const result = rgb1.map((c, i) => Math.round(c + (rgb2[i] - c) * factor))

//     // 转换回十六进制
//     return `#${result.map((c) => c.toString(16).padStart(2, '0')).join('')}`
//   }

//   // 计算基于百分比的颜色
//   const progressColor = computed(() => {
//     const p = props.percentage

//     // 找到当前百分比所在的颜色区间
//     for (let i = 0; i < colorStops.length - 1; i++) {
//       if (p >= colorStops[i].percentage && p <= colorStops[i + 1].percentage) {
//         const factor =
//           (p - colorStops[i].percentage) / (colorStops[i + 1].percentage - colorStops[i].percentage)
//         return interpolateColor(colorStops[i].color, colorStops[i + 1].color, factor)
//       }
//     }

//     return colorStops[colorStops.length - 1].color
//   })

//   // 修改绘制函数中的渐变定义
//   const gradient = ctx.createLinearGradient(0, 0, size, size)
//   gradient.addColorStop(0, progressColor.value)
//   gradient.addColorStop(1, progressColor.value)
  // 创建渐变
    const gradient = ctx.createLinearGradient(0, 0, 0, size)
    gradient.addColorStop(0, props.startColor)
    gradient.addColorStop(1, props.endColor)

  // 绘制外层背景圆环
  ctx.beginPath()
  ctx.arc(center, center, outerRadius, 0, Math.PI * 2)
  ctx.strokeStyle = props.bgColor
  ctx.lineWidth = props.outerStrokeWidth
  ctx.lineCap = 'round'
  ctx.stroke()

  // 设置内阴影效果
  ctx.shadowColor = 'rgba(0, 0, 0, 0.3)';
  ctx.shadowBlur = 10;
  ctx.shadowOffsetY = 3;

  // 绘制外层进度圆环
  ctx.beginPath()
  ctx.arc(center, center, outerRadius, props.startAngle, endAngle, !props.clockwise)//最后一个参数为true表示逆时针
  ctx.strokeStyle = gradient
  ctx.lineWidth = props.outerStrokeWidth
  ctx.lineCap = 'butt'
  ctx.stroke()

  // 先绘制阴影（透明填充）
  ctx.fillStyle = 'rgba(0, 0, 0, 0)';
  ctx.fill();

  // 绘制内层白色圆环（完全填充）
  ctx.beginPath()
  ctx.arc(center, center, innerRadius, 0, Math.PI * 2)
  ctx.strokeStyle = 'rgba(255,255,255, .7)' // 白色圆环
  ctx.lineWidth = props.innerStrokeWidth
  ctx.lineCap = 'round'
  ctx.stroke()
}

// 动画函数
const animateProgress = () => {
  if (!props.animate) {
    drawProgressRing()
    return
  }

  let start: number | null = null
  const duration = props.animationDuration
  const startPercentage = 0
  const targetPercentage = props.percentage

  const animationStep = (timestamp: number) => {
    if (!start) start = timestamp
    const progress = Math.min((timestamp - start) / duration, 1)
    const easeProgress = progress === 1 ? 1 : 1 - Math.pow(2, -10 * progress) // 缓动函数
    const currentPercentage = startPercentage + (targetPercentage - startPercentage) * easeProgress

    drawProgressRing(currentPercentage)

    if (progress < 1) {
      animationFrameId.value = requestAnimationFrame(animationStep)
    }
  }

  // 开始动画
  cancelAnimationFrame(animationFrameId.value || 0)
  animationFrameId.value = requestAnimationFrame(animationStep)
}

// 初始化和更新时绘制
onMounted(() => {
  animateProgress()
})

onUpdated(() => {
  animateProgress()
})

// 监听百分比变化并重绘
watch(
  () => props.percentage,
  () => {
    animateProgress()
  }
)

// 组件卸载时清理
onUnmounted(() => {
  if (animationFrameId.value) {
    cancelAnimationFrame(animationFrameId.value)
  }
})
</script>

<style lang="less" scoped>
.progress-container {
  position: relative;
  display: block;
  transition: all 0.3s ease;
}

.progress-container:hover {
  transform: scale(1.03);
}

.progress-canvas {
  display: block;
  margin: 10px auto;
  transition: all 0.3s ease;
}

.progress-text {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  text-align: center;
  transition: all 0.3s ease;
}

.bottom-number{
    position: relative;
    &::before{
        display: block;
        content: '';
        width: 20px;
        height: 1px;
        background-color: #ddd;
        position: absolute;
        top: 0;
        left: 50%;
        margin-left: -10px;
    }
}

</style>
